﻿using FirstFloor.ModernUI.Windows.Controls;
using Lmondeil.Crm.EF;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Configuration;
using System.Data.EntityClient;
using System.Windows.Forms;
using System.Data.Entity.Infrastructure;

namespace Atlanchim.Crm.Mui.Helpers
{
    public class AdminCommandHelper
    {
        public static void Execute(string commandString)
        {
            try
            {
                string strCommand = commandString.Trim().ToLower();
                bool bSuccess = false;

                if (strCommand == "db reset")
                {
                    ExecuteDBReset();
                    bSuccess = true;
                }

                // FeedBack
                string message = string.Empty;
                if (bSuccess)
                {
                    message = "La commande " + Environment.NewLine + commandString + Environment.NewLine + "a été exécutée avec succès.";
                }
                else
                {
                    message = "La commande " + Environment.NewLine + commandString + Environment.NewLine + "est inconnue.";
                }
                ModernDialog.ShowMessage(message, "AdminCommand", System.Windows.MessageBoxButton.OK);
            }
            catch (Exception exc)
            {
                string message = "La commande " + Environment.NewLine + commandString + Environment.NewLine + "est sortie en echec : " + exc.Message;
                ModernDialog.ShowMessage(message, "AdminCommand", System.Windows.MessageBoxButton.OK);
            }
        }

        /// <summary>
        /// Crée ou recrée une nouvelle base de données
        /// </summary>
        /// <returns>localisation de l'éventuel backup de bases</returns>
        public static string ExecuteDBReset()
        {
            string newFilePath = string.Empty;

            using (CrmContext context = new CrmContext())
            {
                if (context.Database.Exists())
                {
                    // Si la base existe, on la backup
                    string filePath = context.Database.Connection.Database;
                    filePath = filePath.Replace("|DataDirectory|", LocalConstants.Folders.DatabaseFolder + @"\");

                    newFilePath =
                        Path.GetDirectoryName(filePath) + @"\" +
                        Path.GetFileNameWithoutExtension(filePath) +
                        DateTime.Now.Date.ToString("_yyyy-MM-dd") +
                        Path.GetExtension(filePath);

                    File.Copy(filePath, newFilePath);

                    // On supprime la base
                    context.Database.Delete();
                }

                // On crée le dossier si nécessaire
                if (!Directory.Exists(LocalConstants.Folders.DatabaseFolder))
                {
                    Directory.CreateDirectory(LocalConstants.Folders.DatabaseFolder);
                }

                // On crée une nouvelle base
                context.Database.Create();
            }

            // retour de fonction
            return newFilePath;
        }

        /// <summary>
        /// Backupe la base de données
        /// </summary>
        /// <returns>localisation de l'éventuel backup de bases</returns>
        public static string BackupDB()
        {
            string newFilePath = string.Empty;

            using (CrmContext context = new CrmContext())
            {

                if (context.Database.Exists())
                {
                    // Si la base existe, on la backup
                    string filePath = context.Database.Connection.Database;
                    filePath = filePath.Replace("|DataDirectory|", LocalConstants.Folders.DatabaseFolder + @"\");

                    // Sélection du fichier de backup
                    using (OpenFileDialog selectDbDlg = new OpenFileDialog())
                    {
                        selectDbDlg.AddExtension = true;
                        selectDbDlg.Filter = "Fichier de données crm (.sdf)|*.sdf";
                        selectDbDlg.Multiselect = false;
                        selectDbDlg.Title = "Sélectionner le fichier de données.";
                        selectDbDlg.CheckFileExists = false;

                        if (selectDbDlg.ShowDialog() == DialogResult.OK)
                        {
                            string dbFilename = selectDbDlg.FileName;

                            File.Copy(filePath, dbFilename);
                        }
                    }
                }
            }

            // retour de fonction
            return newFilePath;
        }

        /// <summary>
        /// Permet de définir le fichier de base de données
        /// </summary>
        /// <param name="dbPath"></param>
        public static string ExecuteDBSetFile(string dbPath)
        {
            // Création de la chaine de connexion
            EntityConnectionStringBuilder efSb = BuildConnection("ModelCrm", dbPath);
            string cnxString = string.Format("metadata=res://*/ModelCrm.csdl|res://*/ModelCrm.ssdl|res://*/ModelCrm.msl;provider=System.Data.SqlServerCe.4.0;provider connection string='data source=&quot;{0}&quot;'", dbPath);

            // Mise à jour du fichier de config
            Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);

            config.ConnectionStrings.ConnectionStrings.Remove(LocalConstants.CnxString.CST_ConnectionStringName);
            config.ConnectionStrings.ConnectionStrings.Add(
                new ConnectionStringSettings(
                    LocalConstants.CnxString.CST_ConnectionStringName,
                    cnxString));
                    //efSb.ConnectionString));

            config.Save(ConfigurationSaveMode.Modified);
            ConfigurationManager.RefreshSection("connectionStrings");

            using (CrmContext context = new CrmContext())
            {
                context.Database.Connection.ChangeDatabase("CrmContext");
            }

            return cnxString;
        }
        
        /// <summary>
        /// Création de la chaine de connection E.F.
        /// </summary>
        /// <param name="modelName"></param>
        /// <param name="databasePath"></param>
        /// <returns></returns>
        public static EntityConnectionStringBuilder BuildConnection(string modelName, string databasePath)
        {
            var builder = new EntityConnectionStringBuilder();

            builder.Provider = "System.Data.SqlServerCe.4.0";
            builder.Metadata = string.Format(
                "res://*/{0}.csdl|res://*/{0}.ssdl|res://*/{0}.msl",
                modelName);
            builder.ProviderConnectionString = string.Format(
                "'Data Source='{0}''",
                databasePath);

            return builder;
        }

        public static void CreateDBIfMissing(string cnxString)
        {
            using (CrmContext context = new CrmContext())
            {
                context.Database.Connection.ConnectionString = cnxString;
                context.Database.CreateIfNotExists();

                context.Database.Connection.ChangeDatabase("CrmContext");
            }
        }

        /// <summary>
        /// Sélection ou création d'un fichier de base de données
        /// </summary>
        public static void SelectDBFile()
        {
            using (OpenFileDialog selectDbDlg = new OpenFileDialog())
            {
                selectDbDlg.AddExtension = true;
                selectDbDlg.Filter = "Fichier de données crm (.sdf)|*.sdf";
                selectDbDlg.Multiselect = false;
                selectDbDlg.Title = "Sélectionner le fichier de données.";
                selectDbDlg.CheckFileExists = false;

                if (selectDbDlg.ShowDialog() == DialogResult.OK)
                {
                    string dbbFilename = selectDbDlg.FileName;
                    string cnxString = ExecuteDBSetFile(dbbFilename);
                    CreateDBIfMissing(cnxString);
                }
            }
        }
    }
}
